Skip to content

fix: Suppress altair/narwhals warning and fix data URL paths#20

Merged
NikoStein merged 1 commit intomainfrom
feature/vrptw-integration
Nov 30, 2025
Merged

fix: Suppress altair/narwhals warning and fix data URL paths#20
NikoStein merged 1 commit intomainfrom
feature/vrptw-integration

Conversation

@NikoStein
Copy link
Copy Markdown
Collaborator

Summary

  • Added warnings filter to suppress narwhals is_pandas_dataframe warning in Altair 6.x
  • Fixed warehouse_location_part_1.py and warehouse_location_part_2.py to use correct wlp data path instead of cog

Files Changed

  • apps/center_of_gravity.py - added warnings filter
  • apps/warehouse_location_part_1.py - added warnings filter + fixed data URL
  • apps/warehouse_location_part_2.py - added warnings filter + fixed data URL

Test plan

  • Verify center_of_gravity notebook runs without narwhals warning
  • Verify warehouse_location_part_1 loads correct data in WASM mode
  • Verify warehouse_location_part_2 loads correct data in WASM mode

- Add warnings filter to suppress narwhals is_pandas_dataframe warning in all 3 notebooks
- Fix warehouse_location_part_1 and part_2 to use correct wlp data path instead of cog
@NikoStein NikoStein merged commit 6add192 into main Nov 30, 2025
@MarcoGorelli
Copy link
Copy Markdown

hi @NikoStein - sorry to comment here, just wanted to ask about the warning you were seeing from altair

which version of altair were you running? i was under the impression that this had been fixed in more recent versions

@MarcoGorelli
Copy link
Copy Markdown

MarcoGorelli commented Dec 2, 2025

I just tried running

# Import required libraries
import marimo as mo
import altair as alt
import polars as pl
import numpy as np
import requests
import folium
from typing import Optional

def create_cog_example_data():
    """Create 5 example demand points for CoG demonstration."""
    return pl.DataFrame({
        'id': [1, 2, 3, 4, 5],
        'x': [10, 50, 20, 90, 80],
        'y': [20, 20, 80, 90, 5],
        'demand': [50, 200, 300, 80, 400]
    })

def create_interactive_cog_chart():
    """
    Create an interactive chart where points can be clicked to select/unselect.
    The CoG is calculated and displayed dynamically based on selection.
    """
    points = create_cog_example_data()#.to_pandas()

    # Create click selection (multi-select with toggle, start empty)
    # toggle='true' (string) makes every click toggle without needing shift key
    # empty=False means no points are selected initially
    click = alt.selection_point(fields=['id'], toggle='true', clear=False, empty=False)

    # Demand points
    points_chart = alt.Chart(points).mark_circle().encode(
        x=alt.X('x:Q', scale=alt.Scale(domain=[0, 100]), title='X Coordinate'),
        y=alt.Y('y:Q', scale=alt.Scale(domain=[0, 100]), title='Y Coordinate'),
        size=alt.Size('demand:Q', scale=alt.Scale(range=[200, 1000]), legend=None),
        color=alt.condition(
            click,
            alt.value('steelblue'),
            alt.value('lightgray')
        ),
        opacity=alt.condition(
            click,
            alt.value(0.8),
            alt.value(0.3)
        ),
        tooltip=[
            alt.Tooltip('id:O', title='Point ID'),
            alt.Tooltip('x:Q', title='X'),
            alt.Tooltip('y:Q', title='Y'),
            alt.Tooltip('demand:Q', title='Demand')
        ]
    ).add_params(click)

    # Point labels
    labels = alt.Chart(points).mark_text(dy=-15, fontSize=12, fontWeight='bold').encode(
        x='x:Q',
        y='y:Q',
        text='id:O',
        color=alt.condition(
            click,
            alt.value('black'),
            alt.value('gray')
        )
    ).add_params(click)

    # Calculate CoG from selected points using Altair transforms
    cog_chart = alt.Chart(points).transform_filter(
        click
    ).transform_calculate(
        xq='datum.x * datum.demand',
        yq='datum.y * datum.demand'
    ).transform_aggregate(
        sum_xq='sum(xq)',
        sum_yq='sum(yq)',
        sum_q='sum(demand)',
        groupby=[]
    ).transform_calculate(
        cog_x='datum.sum_xq / datum.sum_q',
        cog_y='datum.sum_yq / datum.sum_q'
    ).mark_point(
        shape='cross',
        size=500,
        color='red',
        strokeWidth=4
    ).encode(
        x='cog_x:Q',
        y='cog_y:Q',
        tooltip=[
            alt.Tooltip('cog_x:Q', title='CoG X', format='.1f'),
            alt.Tooltip('cog_y:Q', title='CoG Y', format='.1f')
        ]
    )

    # CoG label
    cog_label = alt.Chart(points).transform_filter(
        click
    ).transform_calculate(
        xq='datum.x * datum.demand',
        yq='datum.y * datum.demand'
    ).transform_aggregate(
        sum_xq='sum(xq)',
        sum_yq='sum(yq)',
        sum_q='sum(demand)',
        groupby=[]
    ).transform_calculate(
        cog_x='datum.sum_xq / datum.sum_q',
        cog_y='datum.sum_yq / datum.sum_q'
    ).mark_text(
        dy=-15,
        fontSize=14,
        fontWeight='bold',
        color='red'
    ).encode(
        x='cog_x:Q',
        y='cog_y:Q'
    )

    # Lines from CoG to selected points
    lines_base = alt.Chart(points).transform_filter(
        click
    ).transform_calculate(
        xq='datum.x * datum.demand',
        yq='datum.y * datum.demand'
    ).transform_joinaggregate(
        sum_xq='sum(xq)',
        sum_yq='sum(yq)',
        sum_q='sum(demand)'
    ).transform_calculate(
        cog_x='datum.sum_xq / datum.sum_q',
        cog_y='datum.sum_yq / datum.sum_q'
    )

    # Draw lines
    lines = lines_base.mark_line(
        color='red',
        strokeWidth=2,
        opacity=0.4,
        strokeDash=[5, 5]
    ).encode(
        x='x:Q',
        y='y:Q',
        x2='cog_x:Q',
        y2='cog_y:Q'
    )

    # Demand labels on lines (at midpoint)
    line_labels = lines_base.transform_calculate(
        mid_x='(datum.x + datum.cog_x) / 2',
        mid_y='(datum.y + datum.cog_y) / 2'
    ).mark_text(
        fontSize=11,
        fontWeight='bold',
        color='red',
        dx=0,
        dy=-5
    ).encode(
        x='mid_x:Q',
        y='mid_y:Q',
        text=alt.Text('demand:Q', format='d')
    )

    return (points_chart + labels + lines + line_labels + cog_chart + cog_label).properties(
        width=500,
        height=500,
        title='Click points to select/unselect for CoG calculation'
    )

_cog_example_plot = create_interactive_cog_chart()

_cog_example_plot

and the plot displays fine, without any warnings:

Screenshot 2025-12-02 145013

@NikoStein
Copy link
Copy Markdown
Collaborator Author

Hi @MarcoGorelli - thanks for reaching out. For me, it also worked fine when running it locally. However, running it using WASM it still get this warning:

/lib/python3.12/site-packages/altair/utils/data.py:71: UserWarning: You passed a <class 'narwhals.stable.v1.DataFrame'> to is_pandas_dataframe.

Hint: Instead of e.g. is_pandas_dataframe(df), did you mean is_pandas_dataframe(df.to_native())?
return _is_pandas_dataframe(obj) or isinstance(
/lib/python3.12/site-packages/altair/utils/data.py:71: UserWarning: You passed a <class 'narwhals.stable.v1.DataFrame'> to is_pandas_dataframe.

Hint: Instead of e.g. is_pandas_dataframe(df), did you mean is_pandas_dataframe(df.to_native())?
return _is_pandas_dataframe(obj) or isinstance(

You can try yourself here: https://d3group.github.io/OM-lecture/center_of_gravity/

I think there might be an older version on micropip maybe.

@MarcoGorelli
Copy link
Copy Markdown

thank you! i see it now, yes, looks like there's altair v 5.4.1 there 😩

🤔 maybe the warning should just be removed from narwhals if it ends up being disruptive like this

@MarcoGorelli
Copy link
Copy Markdown

though https://pyodide.org/en/stable/usage/packages-in-pyodide.html shows that it should already be using altair 5.5 🤔

sorry for the noise 😄 will investigate

@agriyakhetarpal
Copy link
Copy Markdown

marimo is currently using Pyodide 0.27, as some packages we disabled to get the Pyodide 0.28 release out are unfortunately still disabled in Pyodide 0.29. Pyodide 0.27 has an older version of Altair, which you see in the notebook at https://d3group.github.io/OM-lecture/center_of_gravity/. The webpage at pyodide.org/en/stable/usage/packages-in-pyodide.html contains the list of packages on the current 0.29 branch, where Altair has beenh updated.

xref: pyodide/pyodide-recipes#99, marimo-team/marimo#5995

I wonder if there could be a mechanism in marimo to use a newer Pyodide version (JupyterLite supports this) without having to hardcode the version for everyone, though I'm by no means familiar with marimo's codebase 😄

@NikoStein
Copy link
Copy Markdown
Collaborator Author

To be honest I do not know what the issue is but it would be great if this could be fixed. Especially as altair is marimos goto plotting library it would be nice if it works in all modes without warnings :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants